import os
import json
import requests
from typing import Dict, List, Any, Optional

class DeepSeekAPI:
    """DeepSeek API客户端，用于与DeepSeek大模型交互"""

    def __init__(self, api_key=None, api_base="https://api.deepseek.com"):
        """初始化DeepSeek API客户端

        Args:
            api_key: DeepSeek API密钥，如果为None则从环境变量获取
            api_base: DeepSeek API基础URL
        """
        self.api_key = api_key or os.getenv("DEEPSEEK_API_KEY")
        if not self.api_key:
            raise ValueError("DeepSeek API密钥未提供，请设置DEEPSEEK_API_KEY环境变量或在初始化时提供")

        self.api_base = api_base
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}"
        }

    def analyze_fundamental_data(self, stock_code: str, stock_name: str, search_results: List[Dict]) -> Dict:
        """分析股票基本面数据

        Args:
            stock_code: 股票代码
            stock_name: 股票名称
            search_results: 搜索结果列表

        Returns:
            分析结果字典
        """
        # 准备搜索结果文本
        search_texts = []
        if search_results:
            for result in search_results:
                if "title" in result and "content" in result:
                    search_texts.append(f"标题: {result['title']}\n内容: {result['content']}")

        # 如果没有搜索结果，添加提示信息
        if not search_texts:
            search_content = "【注意：未能获取到有效的搜索结果，请基于你的知识进行分析，并在结论中说明数据有限】"
        else:
            search_content = "\n\n".join(search_texts)

        # 构建提示词
        prompt = f"""
你是一位专业的股票分析师，请基于以下关于 {stock_name}（{stock_code}）的信息，进行基本面分析。

以下是搜索到的相关信息：
{search_content}

请提供以下分析：
1. 公司基本情况概述
2. 最近一个月的重要新闻和事件分析
3. 财务状况分析
4. 行业地位和竞争优势
5. 风险因素
6. 基于基本面的股票评级（强烈看多/看多/中性/看空/强烈看空）
7. 基本面分析结论

请以JSON格式返回，包含以下字段：
- company_overview: 公司概述
- recent_news: 最近新闻分析
- financial_analysis: 财务分析
- industry_position: 行业地位
- risk_factors: 风险因素
- rating: 评级
- conclusion: 结论
- sentiment_score: 情感评分（1-10，1最负面，10最正面）
"""

        # 调用API
        response = self._call_api(prompt)

        # 解析结果
        try:
            # 尝试直接解析JSON
            result = json.loads(response)
        except json.JSONDecodeError:
            # 如果直接解析失败，尝试从文本中提取JSON部分
            try:
                json_str = self._extract_json_from_text(response)
                result = json.loads(json_str)
            except (json.JSONDecodeError, ValueError):
                # 如果仍然失败，返回原始响应
                result = {
                    "error": "无法解析JSON响应",
                    "raw_response": response
                }

        return result

    def analyze_technical_data(self, stock_code: str, stock_name: str, stock_data: Any) -> Dict:
        """分析股票技术面数据

        Args:
            stock_code: 股票代码
            stock_name: 股票名称
            stock_data: 股票历史数据DataFrame

        Returns:
            分析结果字典
        """
        # 检查数据是否为空
        if stock_data is None or stock_data.empty:
            # 返回一个基本的分析结果，表明数据不足
            return {
                "price_trend": "数据不足，无法分析",
                "volume_analysis": "数据不足，无法分析",
                "technical_indicators": "数据不足，无法分析",
                "support_resistance": "数据不足，无法分析",
                "patterns": "数据不足，无法分析",
                "short_term_forecast": "数据不足，无法预测",
                "rating": "中性",
                "conclusion": "由于缺乏足够的历史数据，无法进行可靠的技术分析。建议使用其他信息源获取更多数据。",
                "trend_score": 5
            }
            
        # 将DataFrame转换为字符串表示
        try:
            data_str = stock_data.to_string()
        except Exception as e:
            print(f"警告: 转换股票数据时出错: {str(e)}")
            data_str = "数据格式错误，无法显示"

        # 构建提示词
        prompt = f"""
你是一位专业的股票技术分析师，请基于以下 {stock_name}（{stock_code}）的历史交易数据，进行技术面分析。

以下是最近一个月的交易数据（包含各种技术指标）：
{data_str}

请提供以下分析：
1. 价格趋势分析
2. 成交量分析
3. 技术指标分析（MA、MACD、KDJ、RSI等）
4. 支撑位和阻力位
5. 技术形态识别（如头肩顶、双底等，如果有）
6. 基于技术面的短期走势预测
7. 技术面综合评级（强烈看多/看多/中性/看空/强烈看空）

请以JSON格式返回，包含以下字段：
- price_trend: 价格趋势分析
- volume_analysis: 成交量分析
- technical_indicators: 技术指标分析
- support_resistance: 支撑位和阻力位
- patterns: 技术形态
- short_term_forecast: 短期预测
- rating: 评级
- conclusion: 结论
- trend_score: 趋势评分（1-10，1最负面，10最正面）
"""

        # 调用API
        response = self._call_api(prompt)

        # 解析结果
        try:
            # 尝试直接解析JSON
            result = json.loads(response)
        except json.JSONDecodeError:
            # 如果直接解析失败，尝试从文本中提取JSON部分
            try:
                json_str = self._extract_json_from_text(response)
                result = json.loads(json_str)
            except (json.JSONDecodeError, ValueError):
                # 如果仍然失败，返回原始响应
                result = {
                    "error": "无法解析JSON响应",
                    "raw_response": response
                }

        return result

    def generate_final_prediction(self, stock_code: str, stock_name: str,
                                 fundamental_analysis: Dict, technical_analysis: Dict) -> Dict:
        """生成最终预测

        Args:
            stock_code: 股票代码
            stock_name: 股票名称
            fundamental_analysis: 基本面分析结果
            technical_analysis: 技术面分析结果

        Returns:
            最终预测结果字典
        """
        # 检查分析结果是否包含有限数据的指示
        has_limited_data = False
        
        # 检查基本面分析
        if "conclusion" in fundamental_analysis and "数据有限" in fundamental_analysis["conclusion"]:
            has_limited_data = True
        elif "error" in fundamental_analysis:
            has_limited_data = True
            
        # 检查技术面分析
        if "conclusion" in technical_analysis and "数据不足" in technical_analysis["conclusion"]:
            has_limited_data = True
        elif "error" in technical_analysis:
            has_limited_data = True
            
        # 构建提示词
        prompt = f"""
你是一位专业的股票分析师，请基于以下 {stock_name}（{stock_code}）的基本面和技术面分析结果，生成综合预测。

基本面分析结果：
{json.dumps(fundamental_analysis, ensure_ascii=False, indent=2)}

技术面分析结果：
{json.dumps(technical_analysis, ensure_ascii=False, indent=2)}

请综合两方面分析，提供以下内容：
1. 基本面和技术面分析的一致点
2. 基本面和技术面分析的差异点（如果有）
3. 对差异点的解释和调和
4. 明日股价可能的走势预测
5. 投资建议和风险提示

{"注意：分析数据有限，请在结论中明确说明这一点，降低预测的置信度，并提醒投资者谨慎决策。" if has_limited_data else ""}

请以JSON格式返回，包含以下字段：
- consensus_points: 一致点
- difference_points: 差异点
- reconciliation: 差异调和
- tomorrow_forecast: 明日预测，包含预期走势(up/down/flat)和置信度(0-100)
- investment_advice: 投资建议
- risk_warning: 风险提示
- overall_rating: 综合评级（强烈看多/看多/中性/看空/强烈看空）
"""

        # 调用API
        response = self._call_api(prompt)

        # 解析结果
        try:
            # 尝试直接解析JSON
            result = json.loads(response)
        except json.JSONDecodeError:
            # 如果直接解析失败，尝试从文本中提取JSON部分
            try:
                json_str = self._extract_json_from_text(response)
                result = json.loads(json_str)
            except (json.JSONDecodeError, ValueError):
                # 如果仍然失败，返回原始响应
                result = {
                    "error": "无法解析JSON响应",
                    "raw_response": response
                }

        return result

    def _call_api(self, prompt: str, model: str = "deepseek-chat") -> str:
        """调用DeepSeek API

        Args:
            prompt: 提示词
            model: 模型名称

        Returns:
            API响应文本
        """
        url = f"{self.api_base}/v1/chat/completions"

        payload = {
            "model": model,
            "messages": [
                {"role": "user", "content": prompt}
            ],
            "temperature": 0.1,  # 低温度以获得更确定性的回答
            "max_tokens": 4000
        }

        try:
            response = requests.post(url, headers=self.headers, json=payload)

            if response.status_code == 200:
                result = response.json()
                if "choices" in result and len(result["choices"]) > 0:
                    return result["choices"][0]["message"]["content"]
                else:
                    raise ValueError(f"API响应格式异常: {result}")
            else:
                raise ValueError(f"API调用失败: {response.status_code} - {response.text}")

        except Exception as e:
            print(f"API调用异常: {str(e)}")
            raise

    def _extract_json_from_text(self, text: str) -> str:
        """从文本中提取JSON部分

        Args:
            text: 包含JSON的文本

        Returns:
            提取的JSON字符串
        """
        # 查找第一个 { 和最后一个 }
        start = text.find('{')
        end = text.rfind('}')

        if start == -1 or end == -1 or start > end:
            raise ValueError("无法在文本中找到有效的JSON")

        return text[start:end+1]
